package com.yitau.utils;

import java.util.Arrays;
import java.util.Random;

/**
 * 数组工具类
 */
public class ArrayUtils {

    private ArrayUtils() {}

    /** 默认数组长度 */
    public static final int DEFAULT_LEN = 10;
    /** 默认升序数组 */
    public static final int[] DEFAULT_ARRAY_ASC = generateArrayAsc(DEFAULT_LEN);
    /** 默认降序数组 */
    public static final int[] DEFAULT_ARRAY_DESC = generateArrayDesc(DEFAULT_LEN);
    /** 默认随机数组 */
    public static final int[] DEFAULT_ARRAY_RANDOM = generateArrayRandom(DEFAULT_LEN);

    /**
     * Random工具
     */
    private static final class RandomNumberGeneratorHolder {
        static final Random randomNumberGenerator = new Random();
    }

    /**
     * 判断指定位置 index 是否超出数组范围
     * @param array 数组
     * @param index 索引
     * @return 判断结果 true:超出 false:合法
     */
    public static boolean outOfArrayBound(int[] array, int... index) {
        for (int i : index) {
            if (i < 0 || i >= array.length) {
                return true;
            }
        }
        return false;
    }

    /**
     * 交换数组内位置i和位置j的内容
     * @param array 数组
     * @param i 位置i
     * @param j 位置j
     */
    public static void swap(int[] array, int i, int j){
        if (outOfArrayBound(array, i, j)) {
            System.out.println("数组超出边界");
            return;
        }
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    /**
     * 随机打乱数组内容
     * @param array 原数组，执行完后数组内容改变
     */
    public static void shuffle(int[] array) {
        for ( int i = array.length; i > 0; i-- ){
            swap(array, RandomNumberGeneratorHolder.randomNumberGenerator.nextInt(i), i - 1);
        }
    }

    /**
     * 打印数组内容
     *
     * @param array 数组
     */
    public static void printArray(int[] array) {
        for (int i : array) {
            System.out.print(i + " ");
        }
        System.out.println();
    }

    /**
     * 格式化打印数组内容
     *
     * @param array 数组
     * @param index 趟数
     */
    public static void printArray(int[] array, int index) {
        System.out.print("第" + index + "趟：");
        printArray(array);
    }

    /**
     * 生成随机数组，数组内容为 1~len，不重复
     *
     * @param len 数组长度
     * @return 生成的数组
     */
    public static int[] generateArrayRandom(int len) {
        return generateArrayRandom(1, len, len);
    }

    /**
     * 随机指定范围内 n 个不重复的数
     * @param max  指定范围最大值
     * @param min  指定范围最小值
     * @param n  随机数个数
     * @return int[] 随机数结果集
     */
    public static int[] generateArrayRandom(int min, int max, int n){
        if (n <= 0) {
            return new int[0];
        }
        int[] result = generateArrayOrdered(min, max, true);
        shuffle(result);
        return Arrays.copyOfRange(result, 0, n);
    }


    /**
     * 生成指定升降序数组，数组内容为 1~len
     *
     * @param len 数组长度
     * @param type true:升序 false:降序
     * @return 生成的数组
     */
    public static int[] generateArrayOrdered(int len, boolean type) {
        return generateArrayOrdered(1, len, type);
    }

    /**
     * 生成指定升降序数组，数组内容为 [min,max]
     *
     * @param min 下边界
     * @param max 上边界
     * @param type true:升序 false:降序
     * @return int[] 生成的有序数组
     */
    public static int[] generateArrayOrdered(int min, int max, boolean type) {
        int len = max - min + 1;
        if (len <= 0) {
            return new int[0];
        }
        int[] result = new int[len];
        if (type) {
            for (int i = min; i <= max; i++) {
                result[i - min] = i;
            }
        } else {
            for (int i = min; i <= max; i++) {
                result[i - min] = max - i + 1;
            }
        }
        return result;
    }

    /**
     * 生成降序数组，数组内容为 1~len
     *
     * @param len 数组长度
     * @return 生成的数组
     */
    public static int[] generateArrayDesc(int len) {
        return generateArrayOrdered(len, false);
    }

    /**
     * 生成升序数组，数组内容为 1~len
     *
     * @param len 数组长度
     * @return 生成的数组
     */
    public static int[] generateArrayAsc(int len) {
        return generateArrayOrdered(len, true);
    }
}
